package Monitors.GuardedSuspension;


import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

import static ProcessThread.util.Sleeper.sleep;

@Slf4j(topic = "c.GS1")
public class GS1 {
    public static void main(String[] args) {
        //test1();
        test2();
    }

    public static void test1(){
        Guarded guarded = new Guarded();
        new Thread(() -> {
            log.debug("等待结果");
            List<String> o = (List<String>) guarded.get();
            log.debug("结果大小：{}",o.size());
        },"t1").start();

        new Thread(() -> {
            log.debug("执行下载");
            try {
                List<String> download = Downloader.download();
                guarded.set(download);
            } catch (IOException e) {
                e.printStackTrace();
            }

        },"t2").start();
    }

    public static void test2(){
        Guarded1 guarded = new Guarded1();
        new Thread(() -> {
            log.debug("等待结果");
            Object o = guarded.get(2000);
            log.debug("结果：{}",o);
        },"t1").start();

        new Thread(() -> {
            sleep(1);
            log.debug("醒了");
            guarded.set(new Object());

        },"t2").start();
    }

}


class Guarded{
    private Object response;

    public Object get(){
        synchronized (this){
            while (response == null){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return response;
        }
    }


    public void set(Object response){
        synchronized (this){
            this.response = response;
            this.notifyAll();
        }
    }
}

class Guarded1{
    private Object response;
    //millis超时时间
    public Object get(long millis){
        synchronized (this){
            // 1) 记录最初时间
            long begin = System.currentTimeMillis();
            // 2) 已经经历的时间
            long timePassed = 0;
            while (response == null) {
                // 4) 经历时间比超时时间多就应该结束等待
                long waitTime = millis -timePassed ;
                if (waitTime <= 0) {
                    break;
                }
                try {
                    this.wait(waitTime);//使用wite而不用millis防止虚假唤醒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 3) end-begin
                timePassed = System.currentTimeMillis() - begin;
            }
            return response;
        }
    }


    public void set(Object response){
        synchronized (this){
            this.response = response;
            this.notifyAll();
        }
    }
}